
// 用"对象字面量"创建`Object对象(类)`的一个实例
const instance = {
    id: 1001,
    name: '罗睿德',
    age: 18
}

Object.defineProperty( instance, 'gender', { value: '靓仔' } );

console.log( instance );

// Object.getPropertyOf(object)
// 作用: 获得指定对象(object)对应的原型(相当于获取object.__proto__的值)
// 返回: 返回指定对象对应的原型(即object.__proto__)
const p = Object.getPrototypeOf( instance );
// 此时引用变量 instance 指向的实例 对应的原型是 Object.prototype
console.log( p === Object.prototype ); // true
console.log( instance.__proto__ === Object.prototype ); // true

let str = instance.toString(); // 调用从 Object.prototype 继承的 toString 方法
console.log( str );

// 用"对象字面量"定义一个用于充当原型的实例
const proto = {
    eat(food) {
        console.log(`吃${food}`);
    }
}

// Object.setPrototypeOf(object, prototype)
// 作用: 替换指定对象(object)的原型(prototype)
// 返回: 返回被替换了原型的对象(即setPrototypeOf第一个参数传入的对象)
Object.setPrototypeOf( instance, proto );
// 此时 instance 的原型被替换成 proto
console.log( Object.getPrototypeOf(instance) );
// 因此，此时的 instance 可以从 proto 继承属性和方法
instance.eat('驴肉火烧');

// Object.getOwnPropertyNames(object)
// 作用: 获得指定对象(object)的所有自有属性的名称
// 返回: 返回指定对象所有自有属性名组成数组
const propertyNameArray = Object.getOwnPropertyNames( instance );
for(let i = 0 ; i < propertyNameArray.length; i++ ) {
    let name = propertyNameArray[i];
    console.log( name );
}

console.log( '- '.repeat(10) );

// 迭代对象(即实例): 将获得该对象(即实例)所有可枚举属性，包括从原型上继承的属性
for( let name in instance ) {
    console.log( name );
}

console.log( '- '.repeat(10) );

// 用 in 运算符判断指定属性在指定对象上是否存在
// 属性属于对象自有属性 或 属性是从原型继承的属性 时 返回 true
console.log( `id` in instance );
console.log( `name` in instance );
console.log( `age` in instance );
// gender 是 instance 自有的不可枚举属性
console.log( `gender` in instance );
// eat 实际时来自 instance 对应的原型 ( Object.getPrototypeOf(instance) )
console.log( `eat` in instance ); // true
